﻿@namespace MXERP.Blazor.Components
@using System.Runtime.InteropServices;
@using MudBlazor.Services
@typeparam T
@inherits BaseInput<T>
@inject IKeyInterceptorFactory KeyInterceptorFactory
@inject IMdScrollManager MdScrollManager

<CascadingValue Name="Standalone" Value="false" IsFixed="true">
    <CascadingValue Value="@this" IsFixed="true">
        <div class="mud-select-extended" id="@_elementId">
            <MudInputControl Label="@Label" Variant="@Variant" HelperText="@HelperText" HelperTextOnFocus="@HelperTextOnFocus" FullWidth="@FullWidth" Margin="@Margin" Class="@Classname" Style="@Style"
                             Error="@Error" ErrorText="@ErrorText" ErrorId="@ErrorId" Disabled="@Disabled" @onmousedown="@ToggleMenu" Required="@Required" ForId="@FieldId">
                <InputContent>
                    @*DataVisualiserStyle="@($"min-height: 1.1876em;{(HasValue(Value) && Editable == true ? "padding-bottom: 0px" : null)}")"*@
                    <Input @ref="_inputReference" T="string" InputType="@(Editable && !MultiSelection ? InputType.Text : InputType.Hidden)"
                                      Class="@InputClassname" Style="@InputStyle" Margin="@Margin" Placeholder="@Placeholder" Label="@Label"
                                      Variant="@Variant" Immediate="true"
                                      TextUpdateSuppression="false"
                                      ShowVisualiser="@((MultiSelection && SelectedValues?.Any() == true) || !Editable)" DataVisualiserStyle="min-height: 1.1876em"
                                      @bind-Value="@_searchString"
                                      Underline="@Underline"
                                      Disabled="@GetDisabledState()" ReadOnly="@GetReadOnlyState()" Error="@Error" ErrorId="@ErrorId"
                                      Clearable="@Clearable" ForceClearable="@(Clearable && HasValue(Value))" OnClearButtonClick="@ClearButtonClickHandlerAsync"
                                      @attributes="UserAttributes" OnBlur="@HandleOnBlur" ShrinkLabel="@(HasValue(Value) || _isOpen || ShrinkLabel)">

                        <AdornmentEnd>
                            <MudIcon Icon="@_currentIcon" Color="@AdornmentColor" Size="@IconSize" @onclick="OnAdornmentClick" />
                        </AdornmentEnd>

                        <DataVisualiser>
                            <div style="flex-basis: content; flex-grow: 0">
                                @if (!HasValue(Value) && !string.IsNullOrWhiteSpace(Placeholder))
                                {
                                    <MudText Typo="Typo.body1" Class="mud-text-secondary">@Placeholder</MudText>
                                }
                                else if (InputPresenter == ValuePresenter.Chip)
                                {
                                    <MudChipSet T="T" Class="d-flex flex-wrap mud-width-full" AllClosable="@ChipCloseable" OnClose="@ChipClosed">
                                        @{
                                            var collection = Items.Where(x => (MultiSelection ? SelectedValues?.Contains(x.Value) == true : Value?.Equals(x.Value) == true))?.ToList();
                                            if (collection is not null)
                                            {
                                                foreach (var item in CollectionsMarshal.AsSpan(collection))
                                                {
                                                    <MudChip Class="@ChipClass" Value="@item.Value" Text="@(ToStringFunc is not null ? ToStringFunc.Invoke(item.Value) : string.IsNullOrWhiteSpace(item.Text) ? Converter.Set(item.Value) : item.Text)"
                                                             Color="@Color" Size="@ChipSize" Variant="@ChipVariant" @onmousedown:stopPropagation />
                                                }
                                            }
                                        }
                                        @*@if (ItemCollection is not null)
                                    {
                                    foreach (var item in ItemCollection.Where(x => SelectedValues.Contains(x)))
                                    {
                                    <MudChip Class="@ChipClass" Value="@item" Text="@Converter.Set(item)" Color="@Color" Size="@ChipSize" Variant="@ChipVariant" @onmousedown:stopPropagation />
                                    }
                                    }
                                    else
                                    {
                                    foreach (var item in Items.Where(x => (MultiSelection ? SelectedValues.Contains(x.Value) : Value?.Equals(x.Value) == true)) ?? new List<MudComboBoxItem<T>>())
                                    {
                                    <MudChip Class="@ChipClass" Value="item.Value" Text="@(ToStringFunc is not null ? ToStringFunc.Invoke(item.Value) : string.IsNullOrWhiteSpace(item.Text) ? Converter.Set(item.Value) : item.Text)" Color="@Color" Size="@ChipSize" Variant="@ChipVariant" @onmousedown:stopPropagation />
                                    }
                                    }*@
                                    </MudChipSet>
                                }
                                else if (InputPresenter == ValuePresenter.Text && (!Editable || (MultiSelection && Editable)))
                                {
                                    <div style="white-space: break-spaces">@_dataVisualiserText</div>
                                }
                                else if (InputPresenter == ValuePresenter.ItemContent)
                                {
                                    if (SelectedValues is null)
                                    {
                                        <MudText Typo="Typo.body1" Class="mud-text-secondary">@Placeholder</MudText>

                                    }
                                    else if (ItemTemplate is not null)
                                    {
                                        if (Value is not null)
                                        {
                                            @ItemTemplate(Items.FirstOrDefault(x => x.Value?.Equals(Value) == true) ?? new ComboBoxItem<T>())
                                        }
                                        else if (!string.IsNullOrWhiteSpace(Placeholder))
                                        {
                                            <MudText Typo="Typo.body1" Class="mud-text-secondary">@Placeholder</MudText>
                                        }
                                    }
                                    else if (Items.FirstOrDefault(x => x?.Value?.Equals(Value) == true)?.ChildContent is not null)
                                    {
                                        if (MultiSelection)
                                        {
                                            foreach (var item in CollectionsMarshal.AsSpan(Items))
                                            {
                                                if (SelectedValues.Contains(item.Value))
                                                {
                                                    <MudRender>@item.ChildContent</MudRender>
                                                }
                                            }
                                        }
                                        else
                                        {
                                            <MudRender>@Items.FirstOrDefault(x => x.Value?.Equals(Value) == true)?.ChildContent</MudRender>
                                        }
                                    }
                                    else
                                    {
                                        <MudRender>@GetPresenterText()</MudRender>
                                    }
                                }
                            </div>
                        </DataVisualiser>
                        <ChildContent>
                            <div class="@TemplateClass">
                                @if (!HasValue(Value) && !string.IsNullOrWhiteSpace(Placeholder))
                                {
                                    <MudText Typo="Typo.body1" Class="mud-text-secondary">@Placeholder</MudText>
                                }
                            </div>
                        </ChildContent>

                    </Input>

                    <MudPopover Open="true" MaxHeight="@MaxHeight" AnchorOrigin="@AnchorOrigin" TransformOrigin="@TransformOrigin" OverflowBehavior="OverflowBehavior.FlipAlways" Class="@PopoverClassname" RelativeWidth="@RelativeWidth">
                        <CascadingValue Value="@this" IsFixed="true">
                            <div id="@_popoverId" style="@($"overflow-y: auto; max-height: {MaxHeight}px")">
                                @PopoverStartContent
                                @if (MultiSelection)
                                {
                                    <div Style="position: sticky; top: 0px; background-color: var(--mud-palette-background); z-index: 2" @onkeydown:stopPropagation>
                                        @if (Editable)
                                        {
                                            <div class="pa-2">
                                                <TextField id="@($"{_elementId}-autocomplete")" @ref="@_searchbox" T="string" @bind-Value="@_searchString" Margin="Margin.Dense"
                                                                      Variant="Variant.Outlined" Immediate="true" OnKeyDown="@SearchBoxHandleKeyDown" OnKeyUp="@SearchBoxHandleKeyUp"
                                                                      Clearable="@SearchBoxClearable">
                                                    <AdornmentEnd>
                                                        <MudIcon Icon="@Icons.Material.Filled.Search" Color="@Color" />
                                                    </AdornmentEnd>
                                                </TextField>
                                            </div>
                                        }

                                        @if (SelectAll)
                                        {
                                            <div class="@($"mud-combobox-item mud-combobox-item-clickable mud-combobox-item-{Dense.ToDescriptionString()} mud-ripple d-flex")" @onclick="SelectAllItems" @onclick:stopPropagation="true">
                                                <MudCheckBox Class="mx-4" Dense
                                                             @bind-Value="@_allSelected" @onclick="@SelectAllItems"
                                                             IndeterminateIcon="@IndeterminateIcon"
                                                             Size="@CheckBoxSize"
                                                             Color="@EffectiveCheckBoxCheckedColor"
                                                             UnCheckedColor="@EffectiveCheckBoxUnCheckedColor" />

                                                <MudText Typo="GetTypo()" Color="@TextColor">@SelectAllText</MudText>
                                            </div>
                                            <MudDivider />
                                        }
                                    </div>
                                }

                                @ChildContent
                                @if (NoItemsContent is not null && !HasEligibleItems())
                                {
                                    <div class="pa-2">
                                        @NoItemsContent
                                    </div>
                                }
                                @PopoverEndContent
                            </div>
                        </CascadingValue>
                    </MudPopover>
                </InputContent>
            </MudInputControl>
        </div>
    </CascadingValue>

</CascadingValue>
<!-- mousedown instead of click needed to close the menu before OnLostFocus runs -->
<MudOverlay Visible="@_isOpen" @onmousedown="@CloseMenu" LockScroll="@LockScroll" />
